package org.arduomo.serial.ui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import javax.swing.JPanel;

import org.arduomo.serial.controller.SerialController;
import org.arduomo.serial.controller.SerialListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.experimental.chart.plot.CombinedXYPlot;



public class GraphPanel extends JPanel implements SerialListener{
	
	private static final int NUM_CHART_SAMPLES=1000;
	private ArrayList<Integer> aSamples;
	private int numSamples;
	private XYPlot plot1;
	
	
	public GraphPanel () {
		super();
		aSamples=new ArrayList<Integer>();
		numSamples=0;
		
		
//		setSize(new Dimension(100,200));
		setPreferredSize(new Dimension(100,200));
		JFreeChart chart = createChart();
        add( new ChartPanel(chart));
        initialize();
	}
	
	private JFreeChart createChart() {
        // create plot ...
        IntervalXYDataset data1 = getDataSet();
        XYItemRenderer renderer1 = new XYLineAndShapeRenderer(true, false);
        renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
                StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,
                new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0.00")));
        renderer1.setSeriesStroke(0, new BasicStroke(1.0f,
                BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
        renderer1.setSeriesPaint(0, Color.blue);

        DateAxis domainAxis = new DateAxis("Time");
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.02);
        ValueAxis rangeAxis = new NumberAxis("Sensor Out");
        rangeAxis.setAutoRange(false);
        rangeAxis.setUpperBound(255);
        plot1 = new XYPlot(data1, null, rangeAxis, renderer1);
        plot1.setBackgroundPaint(Color.lightGray);
        plot1.setDomainGridlinePaint(Color.white);
        plot1.setRangeGridlinePaint(Color.white);

        CombinedXYPlot cplot = new CombinedXYPlot(domainAxis, rangeAxis);
        cplot.add(plot1, 3);
//        cplot.add(plot1, 2);
        cplot.setGap(8.0);
        cplot.setDomainGridlinePaint(Color.white);
        cplot.setDomainGridlinesVisible(true);


        // return a new chart containing the overlaid plot...
        JFreeChart chart = new JFreeChart("CombinedXYPlotDemo1",
                JFreeChart.DEFAULT_TITLE_FONT, cplot, false);
        chart.setBackgroundPaint(Color.white);
        LegendTitle legend = new LegendTitle(cplot);
        chart.addSubtitle(legend);
        return chart;
	}

	public void initialize() {
		SerialController.getInstance().addListener(this);
	}

	@Override
	public void receivedMessage(String message) {
//		System.out.println("message received: "+ message);
		if (message.compareTo("")!=0) {
			int [] aMessage= parse(message);
			for (int i = 0; i < aMessage.length; i++) {
				if (aMessage[i]!=-1) {
					if (numSamples==NUM_CHART_SAMPLES) {
						aSamples.remove(0);
					} else numSamples++;
					aSamples.add(aMessage[i]);
				}
			}
		}
		updateDataset();
	}
	
	private int[] parse(String message) {
		message=message.trim();
		String [] messageSplitted=message.split(":");
		messageSplitted[1]=messageSplitted[1].substring(1, messageSplitted[1].length()-1);
		String [] valuesSplitted=messageSplitted[1].split(",");
		int [] iMessage=new int[valuesSplitted.length];
		for (int i=0;i<valuesSplitted.length;i++) {
		try {
				iMessage[i]=Integer.parseInt(valuesSplitted[i].trim());
			} catch (NumberFormatException e) {
				iMessage[i]=-1;
//				e.printStackTrace();
			}
		}
		return iMessage;
	}

	private IntervalXYDataset getDataSet() {

        // create dataset 1...
        TimeSeries series1 = new TimeSeries("Series 1");
        for (int i=0;i<numSamples;i++) {
        	series1.add(new Millisecond(100*i,new Second()), aSamples.get(i));
        }
//        series1.add(new Millisecond(100,new Second()), 100);
//        series1.add(new Millisecond(200,new Second()), 200);
//        series1.add(new Millisecond(300,new Second()), 300);
//        series1.add(new Millisecond(400,new Second()), 400);
//        series1.add(new Millisecond(500,new Second()), 100);
//        series1.add(new Millisecond(600,new Second()), 200);
//        series1.add(new Millisecond(700,new Second()), 100);
        
        return new TimeSeriesCollection(series1);
	}
	public void updateDataset(){
		plot1.setDataset(getDataSet());
//		this.repaint();
	}
}
